package com.evolution.model;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.evolution.listeners.OrganismListener;

public class OrganismRegistry {

	private static OrganismRegistry INSTANCE;
	
	private Map<Integer,List<Organism>> registry;
	private int organismIDCount;
	private int totalPopulation;
	
	private List<OrganismListener> listeners;
	
	public static OrganismRegistry getInstance(){
		if(INSTANCE == null){
			INSTANCE = new OrganismRegistry();
		}
		return INSTANCE;
	}
	
	private OrganismRegistry() {
		registry = new HashMap<Integer, List<Organism>>();
		organismIDCount = 0;
		totalPopulation = 0;
		
		listeners = new ArrayList<OrganismListener>();
	}
	
	public void registerOrganism(Organism organism,Organism parent){
		List<Organism> organisms = registry.get(new Integer(organism.getSpeciesID()));
		if(organisms == null){
			organisms = new ArrayList<Organism>();
			registry.put(new Integer(organism.getSpeciesID()), organisms);
		}
		organism.setID(generateID());
		organisms.add(organism);
		
		totalPopulation++;
		
		for(OrganismListener listener : listeners){
			listener.organismRegistered(organism,parent);
		}
	}
	
	public void deregisterOrganism(Organism organism){
		List<Organism> organisms = registry.get(new Integer(organism.getSpeciesID()));
		if(organisms != null){
			organisms.remove(organism);
			totalPopulation--;
			if(organisms.isEmpty()){
				Species species = SpeciesRegistry.getInstance().getSpecies(organism.getSpeciesID());
				SpeciesRegistry.getInstance().makeSpeciesExtinct(species);
			}
			for(OrganismListener listener : listeners){
				listener.organismDeregistered(organism);
			}
		}else{
			throw new IllegalStateException("Could not deregister organism. No registry entry found for organism of that species");
		}
	}
	
	public void addListener(OrganismListener listener){
		listeners.add(listener);
	}
	
	public void removeListener(OrganismListener listener){
		listeners.remove(listener);
	}
	
	public int getTotalPopulation(){
		return totalPopulation;
	}
	
	private int generateID(){
		organismIDCount++;
		return organismIDCount;
	}
}
